home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
012
/
last.arc
/
LASTCOM.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1985-03-14
|
8KB
|
215 lines
{$c-}
{$k-}
{this program is a "stay resident" program which allows the operator to
perform any of the last 10 commands which he had entered by entering an
AltF10 to get a list of them, followed by a function key F1-F10
to select which command to reenter. Command lines which begin with
nonprintable keystrokes are not saved. This program was written as an example
of a TurboPascal stay-resident program}
{declare our constants}
const
our_char = 113; {this is the scan code for AltF10}
scan_offset = 58; {scan code of F1 - 1}
first_row = 5; {window size and position}
first_col = 5;
numb_saved = 10;
windowwidth = 40;
windowlength = 12; {=numb_saved + 2}
CR = $D;
user_int = $68; {place to put out interrupt}
kybrd_int = $16; {BIOS keyboard interrupt}
prog_size = 16000; {approximate size of program --
this much space is reserved upon exit}
{here the global (static type) variables}
type
regtype = record
ax,bx,cx,dx,bp,si,di,ds,es,flags:integer
end;
halfregtype = record
al,ah,bl,bh,cl,ch,dl,dh:byte
end;
const {pur 'regs' in the code segment}
regs : regtype = (ax:0;bx:0;cx:0;dx:0;bp:0;si:0;di:0;ds:0;es:0;flags:0);
feeding_char :boolean = FALSE;
no_cr :boolean = FALSE;
j :integer = 1;
saveds :integer = 0;
var
savreg :regtype; {define a variable for the structures}
halfregs :halfregtype absolute regs; {and for the half registers}
i :integer;
last_lines :array [0..numb_saved] of array[1..60] of integer;
cursorpos :integer;
{.pa}
{include the window manipulation software}
{$i lastwin.inc}
{.pa}
{the following code prints out the previous n commands in
the window previously opened up}
procedure printchoices;
var
i,j : integer;
outchar : byte;
begin
for i := 2 to numb_saved+1 do {loop thru the saved commands}
begin
GoToXY(2,i);
Write('F');Write(((i-1) mod 10):1);Write(')'); {put up the command number}
j := 1;
while ((last_lines[i-1][j] and $FF) <> CR) and (j <> (windowwidth-5)) do
begin
Write(Chr(last_lines[i-1][j] and $FF));
j := j + 1
end
end
end;
{.pa}
{this code processes interrupts to the get_char BIOS interrupt}
procedure process_intr;
begin;
{$i lastsave.inc} {save the input registers}
if halfregs.ah = 0 then {if this is character request...}
begin
if feeding_char then {if we were in the middle of spooling chars...}
begin
regs.ax := last_lines[i][j]; {...fetch the next character...}
j := j + 1;
if (halfregs.al = CR) or (j > 60) then {...if this was the last character...}
begin
feeding_char := false; {...turn spooling off}
j := 1;
if no_cr then
regs.ax := $0;
no_cr := false
end
end
else
begin {(we are not in the middle of spooling)}
Intr (user_int, regs); {perform the BIOS call}
if halfregs.ah <> our_char then {if this wasn't "our" character...}
begin
last_lines[0][j] := regs.ax; {...save the keystroke...}
if j < 60 then
j := j + 1;
if halfregs.al = CR then {...if that was a cr...}
begin
j := 1; {...pop down to next entry...}
if Lo(last_lines[0][1]) <> 0 then {...if the first char was printable...}
for i := numb_saved downto 1 do
last_lines[i] := last_lines[i-1];
for i := 1 to 60 do {...clear last entry}
last_lines[0][i] := $07 shl 8 + CR
end
end
else
begin
savreg.ax := $0300; {fetch the current cursor position}
savreg.bx := $0;
Intr($10,savreg);
cursorpos := savreg.dx;
openwindow; {open up the display window}
printchoices; {now print the last commands}
regs.ax := $0; {read a character from the keyboard}
Intr(user_int,regs);
i := halfregs.ah - scan_offset; {note that 0 maps to 1}
if (i > 25) and (i < 37) then
begin
i := i - 25;
no_cr := true
end;
if (i > 0) and (i <= 10) then
begin {legal input}
regs.ax := last_lines[i][1]; {give him the first char}
if halfregs.al <> CR then
begin
feeding_char := true;
j := 2
end;
end;
closewindow; {put what was there back}
savreg.ax := $0200; {reposition cursor}
savreg.bx := $0;
savreg.dx := cursorpos;
Intr($10,savreg)
end
end
end
else {he's not trying t read a character}
if feeding_char then {if he's spooling characters...}
regs.flags := regs.flags and $FFBF {...clear the zero bit}
else
Intr(user_int,regs);
{$i lastrstr.inc} {restore the registers from 'reg'}
inline($CA/$02/$00) {RETF 02}
end;
{.pa}
{this section of code installs the interrupt routine and makes it permanently
resident interrupt borrower}
{the following dos calls are used:
sys 25- install interrupt address
input al = int number, ds:dx = address to install
sys 35- get interrupt address
input al = int number
output es:bx = address in interrupt
int 27- terminate and stay resident
input dx = size of resident program
}
begin {**main**}
{initialize the variables which the interrupt service routine will use}
for i := 0 to numb_saved do
for j := 1 to 60 do
last_lines[i][j] := $07 shl 8 + CR;
j := 1;
saveds := Dseg; {save the data segment locally}
{now install the interrupt routine}
savreg.ax := $35 shl 8 + user_int; {check to make sure int not already used}
Intr($21,savreg);
if savreg.es <> $00 then
WriteLn ('Interrupt in use -- cant install LASTCOMMAND')
else
begin
WriteLn ('Installing LASTCOMMAND -- press AltF10 to select last command');
savreg.ax := $35 shl 8 + kybrd_int;{get the address that was there}
Intr($21,savreg);
savreg.ax := $25 shl 8 + user_int; {put the address in the user interrupt}
savreg.ds := savreg.es;
savreg.dx := savreg.bx;
Intr($21,savreg);
savreg.ax := $25 shl 8 + kybrd_int;{install interrupt system call}
savreg.ds := cseg;
savreg.dx := Ofs(process_intr); {put our routine address}
Intr ($21,savreg);
{now terminate and stay resident}
savreg.dx := prog_size;
Intr ($27,savreg)
end
end.